﻿/*
 * ParametricTransform
 * 
 * initial implementation : 4.6.2011
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
using System.Runtime.Serialization;
using Petra.Gis.Geometry;


namespace Petra.Gis.ReferenceSystemServices.Transformations
{
  /// <summary>
  /// base class for transformations with parameters
  /// </summary>
  [DataContract(Name = "TRANSFORM")]
  public abstract class ParametricTransform : SRSTransform
  {



    #region constructors


    /// <summary>
    /// xaml constructor
    /// </summary>
    protected ParametricTransform()
      :base()
    {
      _parameters = new TransformParameters();
      //_parameters.OnParametersChanged += new TransformParameters.updateParameters(UpdateTransform);
    }





    //protected ParametricTransform(CoordinateSystem sourceCS,
    //                        CoordinateSystem targetCS,
    //                        DistanceUnit distanceParamUnit,
    //                        AngularUnit angularParamUnit,
    //                        params XParam[] parameters)
    //  : this(sourceCS, targetCS, distanceParamUnit, angularParamUnit, new TransformParameters(parameters))
    //{ }
  
    
    
    
    

    protected ParametricTransform(CoordinateSystem sourceCS,
                        CoordinateSystem targetCS,
                        DistanceUnit distanceParamUnit,
                        AngularUnit angularParamUnit,
                        TransformParameters parameters)
      : base(sourceCS, targetCS)
    {

      // must always init parameters !!!
      //_parameters = new TransformParameters();
      Parameters = parameters;

      //foreach (KeyValuePair<string, double> p in parameters)
      //  if (!_parameters.ContainsKey(p.Key))
      //    _parameters.Add(p.Key, p.Value);

      this.DistanceParameterUnit = distanceParamUnit;
      this.AngularParameterUnit = angularParamUnit;

    }


    #endregion constructors





    private TransformParameters _parameters;

    /// <summary>
    /// set/get Math transform parameters
    /// </summary>
    [DataMember(Name="PARAMS")]
    public virtual TransformParameters Parameters
    {
      get { return _parameters; }
      set
      {
        _parameters = value;
        if (value != null)
          UpdateTransform();
        
      }
    }





    private DistanceUnit _distanceParamUnit;

    /// <summary>
    /// get/set distance type unit for given distance type parameters
    /// ParametricTransform usually contains mix of parameters
    /// in either none, distance or angular untis
    /// </summary>
    [DataMember(Name="PARAM_DIST_UNIT")]
    public DistanceUnit DistanceParameterUnit
    {
      get { return _distanceParamUnit; }
      set
      {
        _distanceParamUnit = value;
        if (value != null)
          UpdateTransform();
      }
    }






    private AngularUnit _angularParamUnit;

    /// <summary>
    /// get/set angular unit for given angular type parameters of transform.
    /// ParametricTransform usually contains mix of parameters
    /// in either none, distance or angular untis
    /// </summary>
    [DataMember(Name = "PARAM_ANGULAR_UNIT")]
    public AngularUnit AngularParameterUnit
    {
      get { return _angularParamUnit; }
      set
      {
        _angularParamUnit = value;
        if (value != null)
          UpdateTransform();
      }
    }





    protected override bool graphCompleted()
    {
      return !(this.AngularParameterUnit == null || this.DistanceParameterUnit == null || !parametersValid() );
    }






    /// <summary>
    /// transform parameter validation
    /// must implement in inherited classes.
    /// </summary>
    /// <returns>true when parameters are valid</returns>
    protected abstract bool parametersValid();


  }

}
